import io
import pathlib
import pickle

import cv2
import numpy
from entity.Operation import Click, Drag, Input


class Image:
    def __init__(self):
        self.img_cv = None
        self.path = ""
        self.project_name = None
        self.scene = None
        self.desc = None
        self.threshold = None
        self.operation = []

    def set(self, path):
        """根据路径解析Image，设置个各个参数值"""
        with open(path, "rb") as file:
            information = file.read()
        if len(information.split(b"__Information__")) == 1:
            return False
        self.path = pathlib.Path(path)
        self.project_name = self.get_information(information, b"__ProjectName__")
        self.scene = self.get_information(information, b"__Scene__")
        self.desc = self.get_information(information, b"__Desc__")
        self.threshold = self.get_information(information, b"__Threshold__")
        self.operation = pickle.load(io.BytesIO(information.split(b"__Information__")[-2].split(b"__Operation__")[1]))
        self.img_cv = gray(cv2.imdecode(numpy.fromfile(str(self.path.absolute()), dtype=numpy.uint8), -1))
        return True

    @staticmethod
    def get_information(information, str_bytes):
        return bytes.decode(information.split(b"__Information__")[-2].split(str_bytes)[1])

    def to_string(self):
        if len(self.operation) == 0:
            return f"[特征信息]" \
                   f"\n路径 = {self.path}" \
                   f"\n项目名 = {self.project_name}" \
                   f"\n场景名 = {self.scene}" \
                   f"\n描述 = {self.desc}" \
                   f"\n阈值 = {self.threshold}" \
                   f"\n[操作信息]" \
                   f"\n按<Tab>键继续..."
        operation_text = ""
        for i in self.operation:
            operation_text += i.get_help()
        return f"[特征信息]" \
               f"\n路径 = {self.path}" \
               f"\n项目名 = {self.project_name}" \
               f"\n场景名 = {self.scene}" \
               f"\n描述 = {self.desc}" \
               f"\n阈值 = {self.threshold}" \
               f"\n[操作信息]" \
               f"{operation_text}"

    def text_to_image(self, text):
        """把Text转换为Image对象"""
        solve_text = self.solve_image(text, True)
        information = solve_text["image"]
        operations = solve_text["operation"]
        self.path = information["路径"]
        self.project_name = information["项目名"]
        self.scene = information["场景名"]
        self.desc = information["描述"]
        self.threshold = information["阈值"]
        self.operation = self.dict_to_object(operations)
        if not self.operation:
            return False
        return True

    @staticmethod
    def dict_to_object(operations):
        """把操作列表的字典转换成Operation Object"""
        _res = []
        for i in operations:
            if i["type"] == "Click":
                _res.extend([Click().set(i)])
                continue
            if i["type"] == "Drag":
                _res.extend([Drag().set(i)])
                continue
            if i["type"] == "Input":
                _res.extend([Input().set(i)])
                continue
            return False
        return _res

    @staticmethod
    def solve_image(image_information, save=False):
        """解析文本框中的特征信息和操作信息"""
        # 基本信息字典
        _res = {}
        _image_dict = {}
        _res["image"] = _image_dict
        features = image_information.split("[特征信息]")[1].split("[操作信息]")[0]
        features = features.split("\n")
        for f in features:
            if len(f.split(" = ")) < 2:
                continue
            key = f.split(" = ")[0]
            value = f.split(" = ")[1]
            _image_dict[key] = value
        # 操作信息
        operations = image_information.split("[特征信息]")[1].split("[操作信息]")[1]
        _res["operation"] = operations.split("\n")
        if "" in _res["operation"]:
            _res["operation"] = list(filter(lambda x: x != "", _res["operation"]))
        if len(_res["operation"]) == 0:
            return _res
        operation_list = []
        operation_dict = {}
        for operation in _res["operation"]:
            if len(operation.split("[")) > 1:
                operation_id = operation.split("[")[1].split("]")[0]
                if operation_id.isdigit():
                    operation_dict = dict()
                    operation_dict["id"] = operation_id
                    operation_list.extend([operation_dict])
            if len(operation.split("type = ")) > 1:
                operation_type = operation.split("type = ")[1].split(" #")[0]
                operation_dict["type"] = operation_type
            if len(operation.split("delay_time = ")) > 1:
                operation_delay_time = operation.split("delay_time = ")[1].split(" #")[0]
                operation_dict["delay_time"] = operation_delay_time
            if len(operation.split("translate = ")) > 1:
                operation_translate = operation.split("translate = ")[1].split(" #")[0]
                operation_dict["translate"] = operation_translate
            if len(operation.split("translate_drag = ")) > 1:
                operation_translate_drag = operation.split("translate_drag = ")[1].split(" #")[0]
                operation_dict["translate_drag"] = operation_translate_drag
            if len(operation.split("text = ")) > 1:
                operation_text = operation.split("text = ")[1].split(" #")[0]
                operation_dict["text"] = operation_text
        # 保存操作时，如果数据不存在delay_time，则删除该操作
        if save:
            for i in operation_list:
                if "delay_time" not in i:
                    operation_list.pop(operation_list.index(i))
        _res["operation"] = operation_list
        return _res

def gray(img):
    # 灰度化处理
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    return gray_img

